package com.changge.common.storage.template.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.changge.common.storage.config.properties.OssProperties;
import com.changge.common.storage.exception.StorageErrorCode;
import com.changge.common.storage.template.AbstractFileUploadStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * OSS文件上传策略
 *
 * @author zhangrongkang
 * @since 2023/12/13
 */
@Slf4j
@Service("ossFileUploadStrategy")
public class OssFileUploadStrategy extends AbstractFileUploadStrategy {

    @Autowired
    private OssProperties ossProperties;

    /**
     * 上传文件
     *
     * @param file     文件数据
     * @param classify 文件分类
     * @param fileName 文件名称
     */
    @Override
    protected void upload(MultipartFile file, String classify, String fileName) {
        // 创建OSS客户端
        OSS ossClient = getOssClient();
        String filePath = classify + fileName;
        try {
            // 参数：仓库名称，文件名称，文件输入流
            ossClient.putObject(ossProperties.getBucketName(), filePath, file.getInputStream());
        } catch (Exception e) {
            log.error("OSS文件上传失败: {}", e.getMessage());
            throw StorageErrorCode.FILE_UPLOAD_EXCEPTION.exception();
        } finally {
            // 关闭阿里云OSS客户端
            ossClient.shutdown();
        }
    }

    /**
     * 获取文件访问路径
     *
     * @param filePath 文件路径
     * @return 文件访问路径
     */
    @Override
    protected String getFileAccessUrl(String filePath) {
        return ossProperties.getAccessUrl() + filePath;
    }

    /**
     * 获取文件存储路径
     *
     * @param filePath 文件路径
     * @return 文件存储路径
     */
    @Override
    protected String getFileStoragePath(String filePath) {
        return ossProperties.getPath() + filePath;
    }

    /**
     * 文件是否存在
     *
     * @param filePath 文件全路径
     * @return true--存在；false--不存在
     */
    @Override
    protected Boolean isExist(String filePath) {
        return getOssClient().doesObjectExist(ossProperties.getBucketName(), filePath);
    }

    /**
     * 批量删除文件
     *
     * @param keys 文件存储路径集合
     * @return 是否删除成功
     */
    @Override
    protected Boolean delete(List<String> keys) {
        // 获取OSS客户端
        OSS ossClient = getOssClient();
        // 创建删除请求
        DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(ossProperties.getBucketName());
        // 赋值需要删除的文件
        deleteRequest.setKeys(keys);
        // 调用删除
        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(deleteRequest);
        // 关闭OSS客户端
        ossClient.shutdown();
        // 返回删除结果
        return deleteObjectsResult.getDeletedObjects().size() == keys.size();
    }

    /**
     * 获取OSSClient操作对象
     *
     * @return OSSClient
     */
    private OSS getOssClient() {
        // 创建OSS客户端
        return new OSSClientBuilder().build(
                // 地域节点
                ossProperties.getEndpoint(),
                // 密钥ID
                ossProperties.getAccessKeyId(),
                // 密钥
                ossProperties.getAccessKeySecret());
    }

}
